package com.hcy.app.screen.music.view

import android.content.Context
import android.util.Log
import androidx.annotation.OptIn
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.media3.common.MediaItem
import androidx.media3.common.PlaybackException
import androidx.media3.common.Player
import androidx.media3.common.util.UnstableApi
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.session.MediaSession
import com.hcy.app.data.dao.SettingsRepository
import com.hcy.app.data.dao.Song
import com.hcy.app.data.dao.SongDao
import com.hcy.app.screen.music.MusicFileManager
import com.hcy.app.screen.music.MusicFileManager.getMusicInfoByPath
import com.hcy.app.screen.music.components.LyricsState
import com.hcy.app.utils.SimpleSnowflake
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import javax.inject.Inject
import kotlin.random.Random

@HiltViewModel
class PlayerViewModel @OptIn(UnstableApi::class)
@Inject constructor(
    private val player: ExoPlayer,
    private val mediaSession: MediaSession,
    private val settingsRepository: SettingsRepository,
    private val songDao: SongDao,
) : ViewModel() {

    val generator = SimpleSnowflake(workerId = 1)

    private val _playerState = MutableStateFlow(PlayerState())
    val playerState: StateFlow<PlayerState> = _playerState.asStateFlow()

    init {
        loadConfig()
//        loadLyrics()
        listenPlayer()
        // 启动定时更新进度（每秒一次）
        viewModelScope.launch {
            while (true) {
                delay(1000) // 每秒触发
                if (player.isPlaying) updateState {
                    copy(currentPosition = player.currentPosition)
                }
            }
        }

    }

    fun loadConfig(){
        viewModelScope.launch(Dispatchers.IO){
            // 初始化时读取设置
            // 加载数据库
            val songs = songDao.findAll()
            updateState { copy(songList = songs ) }
            // 加载配置
            val loopModel =  settingsRepository.getLoopMode()
            updateState { copy(loopModel = loopModel ) }
            val currentSongId = settingsRepository.getCurrentSong()
            updateState { copy(currentSongId = currentSongId ) }
        }
    }

    fun listenPlayer(){
        // 监听播放器状态变化
        player.addListener(object : Player.Listener {
            // 播放状态变化
            override fun onPlaybackStateChanged(state: Int) {
                Log.d("hcy", "onPlaybackStateChanged:  $state")
                when (state) {
                    Player.STATE_READY -> updateState{ copy(duration=player.duration) } // 准备就绪,更新歌曲时长
                    Player.STATE_ENDED -> playNextMedia() // 播放结束
                }
            }
            // 播放/暂停
            override fun onPlayWhenReadyChanged(playWhenReady: Boolean, reason: Int) {
                Log.d("hcy", "onPlayWhenReadyChanged:  $playWhenReady")
                updateState {
                    copy(isPlaying = playWhenReady)
                }
            }
            // 监听歌曲切换
            override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) {
                Log.d("hcy", "onMediaItemTransition:  $mediaItem")
                updateState {
                    copy(currentMediaItem = mediaItem)
                }
            }
            // 错误处理
            override fun onPlayerErrorChanged(error: PlaybackException?) {
                Log.e("hcy", "onPlayerErrorChanged:  $error")
            }
        })
    }

    fun playMedia(mediaItem: MediaItem,songId : Long) {
        if (setMediaItem(mediaItem,songId)){
            player.play()
        }
    }

    fun setMediaItem(mediaItem: MediaItem,songId : Long): Boolean{
        val currentListIndex =  _playerState.value.songList.indexOfFirst{ it.id ==songId }
        if (currentListIndex == _playerState.value.currentListIndex){
            return false
        }
        updateState { copy(currentSongId = songId) }
        updateState { copy(currentListIndex = currentListIndex) }
        viewModelScope.launch { // 在协程中保存数据，因为 suspend  函数只能在协程或者其他 suspend 函数中调用
            settingsRepository.saveSongIndex(songId)
        }
        player.setMediaItem(mediaItem)
        player.prepare()
        return true
    }
    // 点击下一首，强制切换歌曲
    fun clickNextMedia(){
        val song = if ( _playerState.value.loopModel == 2 ){
            _playerState.value.songList[Random.nextInt(0,_playerState.value.songList.size)]
        }else{
            if ( _playerState.value.currentListIndex == _playerState.value.songList.size-1){
                _playerState.value.songList[0]
            }else{
                _playerState.value.songList[_playerState.value.currentListIndex+1]
            }
        }
        playMedia(MediaItem.Builder().setUri(song.filePath).build(),song.id)
    }
    // 播放下一首，如果是单曲模式就还是当前的歌曲
    fun playNextMedia(){
        if ( _playerState.value.loopModel == 0 ){
            val song=_playerState.value.songList[_playerState.value.currentListIndex]
            playMedia(MediaItem.Builder().setUri(song.filePath).build(),song.id)
            return
        }
        clickNextMedia()
    }
    // 点击上一首
    fun clickLastMedia(){
        val song = if ( _playerState.value.currentListIndex == 0 ){
            _playerState.value.songList[0]
        }else{
            _playerState.value.songList[_playerState.value.currentListIndex-1]
        }
        playMedia(MediaItem.Builder().setUri(song.filePath).build(),song.id)
    }

    fun togglePlayPause() {
        if (player.isPlaying) player.pause() else player.play()
    }

    override fun onCleared() {
        player.release()
        mediaSession.release()
    }

    private inline fun updateState(transform: PlayerState.() -> PlayerState) {
        _playerState.update{ state -> state.transform() }
    }

    fun seekTo(position: Long){
        player.seekTo(position)
    }

    // 切换循环模式
    fun toggleLoopMode() {
        viewModelScope.launch {
            val newMode = (_playerState.value.loopModel + 1) % 3 // 0→1→2→0
            settingsRepository.saveLoopMode(newMode)
            updateState { copy(loopModel = newMode) }
        }
    }


    fun reloadMusicList(ctx: Context){
        viewModelScope.launch(Dispatchers.IO) { // 切换到 IO 线程
            // 扫描音乐目录
            val li= MusicFileManager.getAllMusicFiles(ctx)
            // 查询数据库
            val dbLi= songDao.findAll()
            val dbSet = mutableSetOf<String>()
            dbLi.forEach {
                dbSet.add(it.filePath)
                if (!li.contains(it.filePath)){
                    // 删除
                    songDao.delete(it.filePath)
                }
            }
            li.forEach {
                if (!dbSet.contains(it)){
                    // 添加
                    val musInfo = getMusicInfoByPath(ctx,it)
                    musInfo?.run {
                        songDao.insert(
                            Song( generator.nextId(),musInfo.title.toString(),musInfo.artist.toString(),musInfo.path.toString(),"",false,"", System.currentTimeMillis(),false)
                        )
                    }
                }
            }
            updateState { copy(songList=songDao.findAll()) }
        }
    }
}

data class PlayerState(
    val isPlaying: Boolean=false, // 是否处于播放状态
    val currentPosition: Long=0L, // 播放到了哪里
    val duration: Long=0L, // 歌曲总时长
    val currentMediaItem: MediaItem? = null, // 当前正在播放的歌曲
    val lyricsState:LyricsState? = null, // 歌词信息
    val songList: List<Song> = emptyList(), // 全部音乐列表
    val currentListIndex: Int=0, // 当前歌曲在list 中的下标
    val currentSongId: Long=0, // 当前歌曲的ID
    val loopModel: Int=1, // 循环模式,默认使用列表模式
)
